package com.chujian.framework.echo;


import cn.hutool.core.util.ReflectUtil;
import com.chujian.framework.annotation.echo.Echo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 回显解析器
 *
 * @author yj
 * @since 2021-12-11
 */
@Slf4j
public class EchoParser implements IEchoParser {

    /**
     * 回显的类信息级别缓存
     * key: EntityClass value:EchoClassInfo
     */
    private final static Map<Class<?>, EchoClassInfo> CLASS_INFO_CACHE = new ConcurrentHashMap<>(16);

    @Override
    public EchoClassInfo parseClass(Class<?> clazz) {
        EchoClassInfo info = CLASS_INFO_CACHE.get(clazz);
        if (info == null) {
            info = doParseClass(clazz);
        }
        return info;
    }

    @Override
    public EchoFieldInfo parseField(Class<?> clazz, Field field) {
        Echo echo = field.getAnnotation(Echo.class);
        if (null == echo) return null;

        field.setAccessible(true);
        EchoFieldInfo fieldInfo = new EchoFieldInfo()
                .setEcho(echo)
                .setField(field);

        // 目标字段
        if (StringUtils.isNotEmpty(echo.targetField())) {
            Field targetField = ReflectUtil.getField(clazz, echo.targetField());
            if (null != targetField) targetField.setAccessible(true);
            fieldInfo.setTargetField(targetField);
        }

        // 数据服务类
        Class<?> dataServiceClass = echo.dataServiceClass();
        if (IEchoDataService.class.equals(dataServiceClass)) {
            String dataServiceName = StringUtils.isNotEmpty(echo.value())
                    ? echo.value()
                    : StringUtils.isNotEmpty(echo.dataService())
                    ? echo.dataService() : "";
            if (StringUtils.isEmpty(dataServiceName)) {
                log.error("echo未指定数据服务,entityClass:{}, field:{}", clazz.getName(), field.getName());
            } else {
                try {
                    dataServiceClass = Class.forName(dataServiceName);
                } catch (ClassNotFoundException e) {
                    log.error("echo的数据服务类非法,entityClass:{}, field:{}, dataServiceName:{}", clazz.getName(), field.getName(), dataServiceName);
                }
            }
        }
        fieldInfo.setDataServiceClass(dataServiceClass);
        return fieldInfo;
    }

    private EchoClassInfo doParseClass(Class<?> clazz) {
        synchronized (CLASS_INFO_CACHE) {
            EchoClassInfo classInfo = CLASS_INFO_CACHE.get(clazz);
            if (null != classInfo) {
                return classInfo;
            }
            // 解析类
            classInfo = new EchoClassInfo()
                    .setClazz(clazz)
                    .setFieldInfos(new ArrayList<>());
            for (Field field : ReflectUtil.getFields(clazz)) {
                EchoFieldInfo fieldInfo = parseField(clazz, field);
                if (null != fieldInfo) {
                    classInfo.getFieldInfos().add(fieldInfo);
                }
            }
            CLASS_INFO_CACHE.put(clazz, classInfo);
            return classInfo;
        }
    }

}
